#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "cmsis_os2.h"
#include "ohos_init.h"

#include "MQTTClient.h"
#include "wifi_connect.h"

#include "cJSON.h"
#include "dev_fan.h"

static unsigned char sendBuf[1000];
static unsigned char readBuf[1000];
//设置连接WIFI账号密码
#define WIFI_SSID "MY_WIFI"
#define WIFI_PWD "12345678"
//连接物联网云平台地址
#define HOST_ADDR "填入自己的接入mqtt接入地址"
//连接物联网云客户端ID
#define CLIENT_ID    ""
//连接物联网云设备ID
#define DEVICE_ID ""//填入在物联网平台三元鉴权的设备ID
//连接物联网云密码
#define DEVICE_PWD  ""//填入在物联网平台三元鉴权设置的密码
//连接物联网云设备MQTT的订阅和上报Topic
#define PUBLISH_TOPIC "$oc/devices/"DEVICE_ID"/sys/properties/report"
#define SUBCRIB_TOPIC "$oc/devices/"DEVICE_ID"/sys/commands/#" ///request_id={request_id}"
#define RESPONSE_TOPIC "$oc/devices/"DEVICE_ID"/sys/commands/response" ///request_id={request_id}"
#define SERVICE_ID  "sz_fan"//设置产品服务ID
//设置设备状态指令
#define OFF     "OFF"
#define ON      "ON"
Network network;
MQTTClient client;
//设备驱动状态
int led_sta=0,fan_sta=0;
//接收到控制指令返回上报
void messageCmdback(char *request_id)
{
    int rc;
    char rsptopic[128]={0};
    sprintf(rsptopic,"%s/request_id=%s",RESPONSE_TOPIC,request_id);
    printf("rsptopic = %s\n",rsptopic);
    MQTTMessage message;
    char payload[300];
    message.qos = 0;
    message.retained = 0;
    message.payload = payload;
    sprintf(payload, "{ \
    \"result_code\": 0, \
    \"response_name\": \"COMMAND_RESPONSE\", \
    \"paras\": { \
        \"result\": \"success\" \
    } \
    }" );
    message.payloadlen = strlen(payload);
    //publish the msg to responese topic
    if ((rc = MQTTPublish(&client, rsptopic, &message)) != 0) {
        printf("Return code from MQTT publish is %d\n", rc);
        NetworkDisconnect(&network);
        MQTTDisconnect(&client);
    }
}
//接收到控制指令进行对应处理控制
void messageArrived(MessageData* data)
{
    int rc;
    printf("Message arrived on topic %.*s: %.*s\n", data->topicName->lenstring.len, data->topicName->lenstring.data,
           data->message->payloadlen, data->message->payload);
   //get request id
    char *request_id_idx=NULL;
    char request_id[20]={0};
    request_id_idx = strstr(data->topicName->lenstring.data,"request_id=");
    strncpy(request_id,request_id_idx+11,19);
    printf("request_id = %s\n",request_id);
    //create response topic
    char rsptopic[128]={0};
    sprintf(rsptopic,"%s/request_id=%s",RESPONSE_TOPIC,request_id);
    printf("rsptopic = %s\n",rsptopic);
    printf("msg=%s\n",data->message->payload);

    cJSON *root = cJSON_ParseWithLength( data->message->payload, data->message->payloadlen);
    if(root != NULL){
        cJSON *cmd_name = cJSON_GetObjectItem(root,"command_name");
        if(cmd_name != NULL){
            char *cmd_name_str = cJSON_GetStringValue(cmd_name);
            if(strcmp(cmd_name_str,"set_fan") == 0){
                cJSON *para_obj = cJSON_GetObjectItem(root,"paras");
                cJSON *status_obj = cJSON_GetObjectItem(para_obj,"Switch");
                char *data = NULL;
                 data = cJSON_GetStringValue(status_obj);
                 if(data != NULL){
                    if(strcmp(data,OFF) == 0)
                    {
                        fan_sta = motor_speed(0);
                        fan_sta = 0;
                    }
                    else{
                        cJSON *status2_obj = cJSON_GetObjectItem(para_obj,"Switch");
                        double data2 ;
                        data2 = cJSON_GetNumberValue(status2_obj);
                        fan_sta = motor_speed(data2);
                        printf("set fan %d",data2);
                        fan_sta = 1;
                    }
                    printf("fan_sta = %d\n",fan_sta);
                }
            }else if(strcmp(cmd_name_str,"led_control") == 0){
                cJSON *para_obj = cJSON_GetObjectItem(root,"paras");
                cJSON *status_obj = cJSON_GetObjectItem(para_obj,"led");
                char *data = NULL;
                 data = cJSON_GetStringValue(status_obj);
                 if(data != NULL){
                    if(strcmp(data,OFF) == 0)
                    {
                        led_sta = led_control(0);
                        led_sta = 0;
                    }
                    else{
                        led_sta = led_control(1);
                        led_sta = 1;
                    }
                    printf("led_sta = %d\n",led_sta);
                }
            }
            messageCmdback(request_id);
         
        }
        cJSON_Delete(root);
    }
}
//对物联网云平台进行通讯程序
static void MQTTDemoTask(void)
{
    printf(">> MQTTDemoTask ...\n");
    printf(">>GPIO Init");
    motor_init();
    led_init();
    //wifi连接
    printf(">>wifi Init");
    WifiConnect(WIFI_SSID, WIFI_PWD);
    printf("Starting ...\n");
    int rc, count = 0;
    // MQTTClient client;
    int PowLed = 0;
    //进行MQTT连接处理
    NetworkInit(&network);
    printf("NetworkConnect  ...\n");
begin:
    //配置MQTT连接数据
    NetworkConnect(&network, HOST_ADDR, 1883);
    printf("MQTTClientInit  ...\n");
    MQTTClientInit(&client, &network, 2000, sendBuf, sizeof(sendBuf), readBuf, sizeof(readBuf));
    //配置物联网云平台MQTT设备ID
    MQTTString clientId = MQTTString_initializer;
    clientId.cstring = CLIENT_ID; 
    //配置物联网云平台MQTT用户名
    MQTTString userName = MQTTString_initializer;
    userName.cstring = DEVICE_ID; 
    //配置物联网云平台MQTT用户密码
    MQTTString password = MQTTString_initializer;
    password.cstring = DEVICE_PWD; 
    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    data.clientID = clientId;
    data.username = userName;
    data.password = password;
    data.willFlag = 0;
    data.MQTTVersion = 4;
    data.keepAliveInterval = 60;
    data.cleansession = 1;
    //连接物联网云平台
    printf("MQTTConnect  ...\n");
    rc = MQTTConnect(&client, &data);
    if (rc != 0) {
        printf("MQTTConnect: %d\n", rc);
        NetworkDisconnect(&network);
        MQTTDisconnect(&client);
        osDelay(200);
        goto begin;
    }
  
    //配置物联网云平台MQTT订阅对应指令Topic
    printf("MQTTSubscribe  ...\n");
    rc = MQTTSubscribe(&client, SUBCRIB_TOPIC, 0, messageArrived);
    if (rc != 0) {
        printf("MQTTSubscribe: %d\n", rc);
        osDelay(200);
        goto begin;
    }
  
    //循环向物联网云平台发送传感器数据
    while (1) {
        MQTTMessage message;
        // char *publishtopic="$oc/devices/test_fan_1/sys/properties/report";
        char payload[1000]={0};
        cJSON *root = cJSON_CreateObject();
        if(root != NULL){
            cJSON *serv_arr = cJSON_AddArrayToObject(root, "services");
            cJSON *arr_item =  cJSON_CreateObject();
            cJSON_AddStringToObject(arr_item,"service_id",SERVICE_ID);
            cJSON *pro_obj = cJSON_CreateObject();
            cJSON_AddItemToObject(arr_item,"properties",pro_obj);
            
            cJSON_AddNumberToObject(pro_obj,"temp",55.5);
            cJSON_AddNumberToObject(pro_obj,"humi",60.1);
            // if(led_sta == 0){
            //     cJSON_AddStringToObject(pro_obj,"led",OFF);
            // }
            // else{
            //     cJSON_AddStringToObject(pro_obj,"led",ON);
            // }
            // if(fan_sta == 0){
            //     cJSON_AddStringToObject(pro_obj,"fan",OFF);
            // }
            // else{
            //     cJSON_AddStringToObject(pro_obj,"fan",ON);
            // }
            cJSON_AddItemToArray(serv_arr,arr_item);
            char *palyload_str = cJSON_PrintUnformatted(root);
            strcpy(payload,palyload_str);
            cJSON_free(palyload_str);
            cJSON_Delete(root);
        }
        message.qos = 0;
        message.retained = 0;
        message.payload = payload;
        message.payloadlen = strlen(payload);
        if ((rc = MQTTPublish(&client, PUBLISH_TOPIC, &message)) != 0) {
            printf("Return code from MQTT publish is %d\n", rc);
            NetworkDisconnect(&network);
            MQTTDisconnect(&client);
            goto begin;
        }else{
            printf("mqtt publish success:%s\n",payload);
        }
        MQTTYield(&client, 5000);
    }
}    
//创建智能风扇任务程序
static void MQTTDemo(void)
{
    osThreadAttr_t attr;
    attr.name = "MQTTDemoTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 10240;
    attr.priority = osPriorityNormal;
    if (osThreadNew((osThreadFunc_t)MQTTDemoTask, NULL, &attr) == NULL) {
        printf("[MQTT_Demo] Failed to create MQTTDemoTask!\n");
    }
}

APP_FEATURE_INIT(MQTTDemo);